home *** CD-ROM | disk | FTP | other *** search
- /* File: meshrand.c
- ** Author: Charles Loop
- ** Purpose: Contains routines for generating random points on a
- ** (nonsubdivided) mesh.
- ** Last Modified: 11 Nov, 1987
- ** Reason : Creation.
- **
- */
-
- #include "randgen.h"
- #include "graphics.h"
- #include "mesh.h"
-
- static double SurfaceArea;
- static PointType4D p;
-
-
- /* compute area of triangle rst */
-
- double area(r,s,t)
- PointType4D *r,*s,*t;
- {
- PointType4D a,b,n;
- double norm;
-
- a.P[X] = s->P[X] - r->P[X]; a.P[Y] = s->P[Y] - r->P[Y]; a.P[Z] = s->P[Z] - r->P[Z];
- b.P[X] = t->P[X] - r->P[X]; b.P[Y] = t->P[Y] - r->P[Y]; b.P[Z] = t->P[Z] - r->P[Z];
-
- n.P[X] = a.P[Y]*b.P[Z] - b.P[Y]*a.P[Z];
- n.P[Y] = a.P[Z]*b.P[X] - b.P[Z]*a.P[X];
- n.P[Z] = a.P[X]*b.P[Y] - b.P[X]*a.P[Y];
-
- if ((norm = n.P[X]*n.P[X] + n.P[Y]*n.P[Y] + n.P[Z]*n.P[Z]) < epsilon)
- return epsilon;
- else
- return sqrt(norm)/2.0;
-
- }
-
- /*****************************************************************************/
-
- Partition(m)
- Mesh *m;
- {
- Mesh *mp;
-
- if (m) {
- if (m->type == MESH) {
- if (m->sub.m) {
- for (mp = m->sub.m; mp != (Mesh *) 0; mp = mp->next)
- Partition(mp);
- }
- m->r = SurfaceArea;
- }
- else if (m->type == FACE) {
- if (m->sub.e) {
-
- SurfaceArea += area(m->sub.e->p,
- m->sub.e->next->p,
- m->sub.e->next->next->p);
-
- m->r = SurfaceArea;
-
- }
- }
- }
- }
-
- /*****************************************************************************/
-
- MeshPartition(m)
- Mesh *m;
- {
- SurfaceArea = 0.0;
- Partition(m);
- }
-
- /*****************************************************************************/
-
- RMP(r,s,t)
- PointType4D *r,*s,*t;
- {
- double u,v,w,uvw;
-
- u = random_unif(0.0, 1.0);
- v = random_unif(0.0, 1.0);
- w = random_unif(0.0, 1.0);
- uvw = u + v + w;
- u = u/uvw; v = v/uvw; w = w/uvw;
-
- p.P[X] = u*r->P[X] + v*s->P[X] + w*t->P[X];
- p.P[Y] = u*r->P[Y] + v*s->P[Y] + w*t->P[Y];
- p.P[Z] = u*r->P[Z] + v*s->P[Z] + w*t->P[Z];
-
- }
-
- /*****************************************************************************/
-
- FindFace(m,r)
- Mesh *m;
- double r;
- {
- Mesh *mp;
- PointType4D Rp0, Rp1, Rp2;
-
- if (m) {
- if (m->type == MESH) {
- if (mp = m->sub.m) {
-
- while ((mp != (Mesh *) 0) && (r > mp->r))
- mp = mp->next;
-
- FindFace(mp,r);
- }
- }
- else if (m->type == FACE) {
- if (m->sub.e) {
-
- RMP(m->sub.e->p,
- m->sub.e->next->p,
- m->sub.e->next->next->p);
-
- }
- }
- else if (m->type == TRIANGLE) {
- Rp0 = CreatePoint4D(m->sub.t->V[0]->x, m->sub.t->V[0]->y,
- m->sub.t->V[0]->z, 1.0);
- Rp1 = CreatePoint4D(m->sub.t->V[1]->x, m->sub.t->V[1]->y,
- m->sub.t->V[1]->z, 1.0);
- Rp2 = CreatePoint4D(m->sub.t->V[2]->x, m->sub.t->V[2]->y,
- m->sub.t->V[2]->z, 1.0);
- RMP(&Rp0, &Rp1, &Rp2);
- }
- else {
- p.P[X] = random_unif(m->box[X][MIN], m->box[X][MAX]);
- p.P[Y] = random_unif(m->box[Y][MIN], m->box[Y][MAX]);
- p.P[Z] = random_unif(m->box[Z][MIN], m->box[Z][MAX]);
- }
- }
- }
-
-
- /*****************************************************************************/
-
- PointType4D
- MeshRandomPoint(m)
- Mesh *m;
- {
-
- double r;
-
- if( m == (Mesh *)0 ) {
- fprintf(stderr,"Error : Invalid mesh for random point generation\n");
- exit(1);
- }
- if( m->r < epsilon ) {
- fprintf(stderr,"Error: Mesh has no surface area \n");
- exit(1);
- }
-
- r = random_unif(0.0, m->r);
- FindFace(m,r);
- return CreatePoint4D(p.P[X], p.P[Y], p.P[Z], 1.0);
-
-
- }
-